import gobject
import socket


import apscan
import device

# For Nokia stuff
import dbus

import logging
logger = logging.getLogger('util.connectivity')
class Connectivity(gobject.GObject):
    
    __gsignals__ = {
        'disconnected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,gobject.TYPE_BOOLEAN)),
        'connected' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,)),
        'connecting' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                (gobject.TYPE_PYOBJECT,)),
    }       
    
    EXTERNAL = 3
    DISCONNECTED = 4
    
    MODE_INF = 1
    MODE_AD_HOC = 2
    
    def __init__(self, interfaces):
        gobject.GObject.__init__(self)
        gobject.timeout_add(5000, self.__update)
        
        self.__interfaces = interfaces
        self.__current_state = Connectivity.DISCONNECTED
        self.__update()
        self.__last_aps = {}
        
    def __update(self):
        def check_external():
            remote = ('www.google.com', 80)
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(1)
            try:
                s.connect(remote)
                return True
            except socket.gaierror, e:
                return False
            
        def determine_mode():
            current = apscan.current('eth1')
            mode = current['mode']
            if mode == 'Managed':
                return Connectivity.MODE_INF
            elif mode == 'Ad-Hoc':
                return Connectivity.MODE_AD_HOC
            else:
                raise ValueError('Got an unknown mode: %s' + (mode,))
        
        def scan():
            # TODO: Replace this with self.interfaces 
            aps = apscan.scan('eth1')
            return aps
        
        external = check_external()
        mode = determine_mode()
        aps = scan()
        
        print external
        print mode
        print aps
        
        if not external and aps is not self.__last_aps:
            # Choose an AP that might give connectivity
            from operator import itemgetter
            def unenc(x):
                if 'encrypted' in x:
                    return x['encrypted'] != True
                else:
                    return False
            aps = filter(unenc, aps)
            aps = sorted(aps, key=itemgetter('level'))
            self.__try_connect(aps[0])
            self.__last_aps = aps
        return True
    
    def __try_connect(self, ap):
        if device.current() == device.LINUX:
            pass
        elif device.current() == device.NOKIA_TABLET:
            bus = dbus.SystemBus()
            icd = bus.get_object('com.nokia.icd',
                           '/com/nokia/icd')
            icd.com.nokia.icd.connect(ap['essid'], 0)
# dbus-send --type=method_call --system --dest=com.nokia.icd /com/nokia/icd com.nokia.icd.connect string:${IAP} uint32:0

if __name__ == '__main__':
    c = Connectivity([])
    